﻿using Aliyun.OSS;
using COSXML;
using COSXML.Auth;
using COSXML.Common;
using COSXML.Model.Object;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NPOI.OpenXmlFormats.Vml;
using System.ComponentModel.DataAnnotations;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.ConfigOptions;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Core.Models;
using WalkingTec.Mvvm.Core.Support.FileHandlers;
using static COSXML.Model.Tag.ListAllMyBuckets;
using DeleteObjectRequest = COSXML.Model.Object.DeleteObjectRequest;
using PutObjectRequest = COSXML.Model.Object.PutObjectRequest;
using PutObjectResult = COSXML.Model.Object.PutObjectResult;

namespace WTMFileHandlerExtensions.Tencent
{
    [Display(Name = "cos")]
    public class WtmCosFileHandler : WtmFileHandlerBase
    {
        public WtmCosFileHandler(WTMContext wtm) : base(wtm)
        {
            _config = wtm.ServiceProvider.GetRequiredService<IOptions<TencentCosConfig>>().Value;
        }

        private TencentCosConfig _config;

        private CosXmlServer CreateCosClient()
        {
            var cosXmlConfig = new CosXmlConfig.Builder()
                  .SetConnectionTimeoutMs(60000)
                  .SetReadWriteTimeoutMs(40000)
                  .IsHttps(true)  //设置默认 HTTPS 请求
                  .SetRegion(_config.Region)  //设置一个默认的存储桶地域
                  .SetAppid(_config.AppId)
                  .SetDebugLog(true)  //显示日志
                  .Build();  //创建 CosXmlConfig 对象

            var cosCredentialProvider = new DefaultQCloudCredentialProvider(
                      _config.SecretId, _config.SecretKey, 600);

            return new CosXmlServer(cosXmlConfig, cosCredentialProvider);
        }

        public override Stream GetFileData(IWtmFile file)
        {
            var client = CreateCosClient();
            var rv = new MemoryStream();

            GetObjectBytesRequest request = new GetObjectBytesRequest(_config.BucketName,file.Path);
            GetObjectBytesResult result = client.GetObject(request);
            byte[] content = result.content;
            rv.Write(content);
            rv.Position = 0;
            return rv;
        }


        public override (string path, string handlerInfo) Upload(string fileName, long fileLength, Stream data, string group = null, string subdir = null, string extra = null)
        {
            var ext = string.Empty;
            if (string.IsNullOrEmpty(fileName) == false)
            {
                var dotPos = fileName.LastIndexOf('.');
                ext = fileName.Substring(dotPos + 1);
            }

            string pathHeader = "";
            if (string.IsNullOrEmpty(subdir) == false)
            {
                pathHeader = Path.Combine(pathHeader, subdir);
            }
            else
            {
                var sub = WtmFileProvider._subDirFunc?.Invoke(this);
                if (string.IsNullOrEmpty(sub) == false)
                {
                    pathHeader = Path.Combine(pathHeader, sub);
                }
            }
            var fullPath = Path.Combine(pathHeader, $"{Guid.NewGuid().ToNoSplitString()}.{ext}");
            fullPath = fullPath.Replace("\\", "/");
            var imagetypes = new string[] { "jpg", "jpeg", "bmp", "tif", "gif", "png" };
            ObjectMetadata md = new ObjectMetadata();
            ext = ext.ToLower();
            if (imagetypes.Contains(ext))
            {
                md.ContentType = "image/jpg";
            }

            var client = CreateCosClient();

            PutObjectRequest putObjectRequest = new PutObjectRequest(_config.BucketName, fullPath, data);
            PutObjectResult result = client.PutObject(putObjectRequest);

            if (result.httpCode == 200)
            {
                return (fullPath, _config.GroupName);
            }
            else
            {
                return (null, null);
            }
        }

        public override void DeleteFile(IWtmFile file)
        {
            
            try
            {
                var client = CreateCosClient();
                client.DeleteObject(new DeleteObjectRequest(_config.BucketName,file.Path));
            }
            catch { }
            return;
        }
    }
}
